package org.atm.service;

import java.security.MessageDigest;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.atm.domain.ATMCard;
import org.atm.domain.Account;
import org.atm.domain.Client;
import org.atm.domain.UserRole;
import org.atm.util.Utils;

@Stateless
public class ClientServiceImpl implements ClientService {

    @Resource(name = "mail/atm")
    private Session mailatm;
    @PersistenceContext(unitName = "comp-5541-atmPU")
    private EntityManager entityManager;

    public void persist(Client client) {
        entityManager.merge(client);
    }

    public Client getById(int clientId) {
        return entityManager.find(Client.class, clientId);
    }

    public Client getByATMCardNumber(String cardNumber) {
        return entityManager.createNamedQuery("Client.findByCardNumber", Client.class).
                setParameter("cardNumber", cardNumber).
                getSingleResult();
    }

    public List<Client> getAll() {
        return entityManager.createNamedQuery("Client.findAll", Client.class).getResultList();
    }

    public List<Client> getAllNew() {
        return entityManager.createNamedQuery("Client.findAllNew", Client.class).getResultList();
    }

    public void approveClient(Client client) throws Exception {
        final String cardNumber = Utils.generateRandomInteger(100000, 999999) + "";
        final String pin = Utils.generateRandomInteger(100000, 999999) + "";

        ATMCard card = new ATMCard();
        card.setCardNumber(cardNumber);
        String pinMD5 = Utils.getMD5Hash(pin);
        card.setPIN(pinMD5);
        client.setATMCard(card);

        Account chequingAccount = Account.createAccount(Account.CHEQUING);
        client.addAccount(chequingAccount);
        Account savingsAccount = Account.createAccount(Account.SAVINGS);
        client.addAccount(savingsAccount);

        client.setApproved();
        entityManager.merge(client);

        UserRole userRole = new UserRole(cardNumber, "CLIENT");
        entityManager.persist(userRole);

        String subject = "ATM - Registration";
        String body = "Hello, \n\nYour ATM registration has been approved.\n\nUse the following ATM Card to authenticate with the ATM.\n"
                + "\nCard number: " + cardNumber
                + "\nPIN: " + pin;
        sendMail(client.getEmail(), subject, body);

    }

    public void rejectClient(Client client) {
        client.setRejected();
        entityManager.merge(client);
    }

    private void sendMail(String email, String subject, String body) throws NamingException, MessagingException {
        MimeMessage message = new MimeMessage(mailatm);
        message.setSubject(subject);
        message.setRecipients(RecipientType.TO, InternetAddress.parse(email, false));
        message.setText(body);
        Transport.send(message);
    }
}
